#include<stdio.h>
#include<fcntl.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>
#include "../include/meta.h"
#include "../include/vfs_errorcodes.h"

void displayAll(node*, FILE*);

char* list_dir(char dir_name[100],int flag,char* outputfile)
{	
	char result[100];	
	if((strcmp(dir_name,"")==0)||(strcmp(outputfile,"")==0))
		{
		strcpy(result,"listdir_FAILURE ");
		strcat(result,ERR_VFS_LISTDIR_00);
		sprintf(str, "%s",result);
		return str;
		}

	if(root==NULL)
		{
		strcpy(result,"listdir_FAILURE ");
		strcat(result,ERR_VFS_LISTDIR_03);
		sprintf(str, "%s",result);
		return str;
		}


	FILE *fop;
	fop=fopen(outputfile,"w");
	if(fop==NULL)
		{
		strcpy(result,"listdir_FAILURE ");
		strcat(result,ERR_VFS_LISTDIR_04);
		sprintf(str, "%s",result);
		return str;
		}
	
	node *srcnode= (node *) malloc(sizeof(node));		
	node *destnode = (node *) malloc(sizeof(node));
	node *rootnode = (node *) malloc(sizeof(node));
	node *prev= (node *) malloc(sizeof(node));


	char *token;
	char dir_name1[100],str1[100];

	if(dir_name[strlen(dir_name)-1]!='/')
		strcat(dir_name,"/");

	strcpy(dir_name1,dir_name);
	token=strtok(dir_name1,"/");
	//printf("dir_name%s\n",dir_name);
	int index;
		
	
	if(flag==1)					//Recursive Listing
	{	

		
		index=bst_search(bstroot,dir_name);

		if(index== -1)
		{
		strcpy(result,"listdir_FAILURE ");
		strcat(result,ERR_VFS_LISTDIR_01);
		sprintf(str, "%s",result);
		return str;
		}		//"CANNOT_FIND_SPECIFIED_PATH_OR_DIR"


		if(strcmp(fd[index].file_type,"folder")!=0)
		{
		strcpy(result,"listdir_FAILURE ");
		strcat(result,ERR_VFS_LISTDIR_01);
		sprintf(str, "%s",result);
		return str;
		}

		rootnode = root;
			
		if(strcmp(root->data,token)!=0)							
		{
		strcpy(result,"listdir_FAILURE ");
		strcat(result,ERR_VFS_LISTDIR_01);
		sprintf(str, "%s",result);
		return str;
		}
					
		while(token!=NULL)
		{
					
			if(strcmp(rootnode->data,token)==0) // match
			{
			 prev = rootnode;
			 rootnode=rootnode->lchild;	 
			}

			else if(strcmp(rootnode->data,token)!=0) // no match
			{
			while((rootnode->rchild!=NULL)&&(strcmp(rootnode->data,token)!=0))
				rootnode=rootnode->rchild;
						 
			if(strcmp(rootnode->data,token)==0)
				{
				prev = rootnode;
				rootnode=rootnode->lchild;
				}
			}
				
		token=strtok(NULL,"/");
		}

		srcnode = prev;
			//displayTree(srcnode->lchild);
		displayAll(srcnode->lchild, fop);
		
		strcpy(result,"listdir_SUCCESS");
		sprintf(str, "%s",result);
		return str;
		
	}

	else if(flag==0)	//non-recursive
	{	

	index=bst_search(bstroot,dir_name); //printf("dir %d: %s\n",index,dir_name);

		if(index== -1)
		{
		strcpy(result,"listdir_FAILURE ");
		strcat(result,ERR_VFS_LISTDIR_01);
		sprintf(str, "%s",result);
		return str;
		}

		if(strcmp(fd[index].file_type,"folder")!=0)
		{
		strcpy(result,"listdir_FAILURE ");
		strcat(result,ERR_VFS_LISTDIR_01);
		sprintf(str, "%s",result);
		return str;
		}

		rootnode = root;
					
		if(strcmp(root->data,token)!=0)							
		{
		strcpy(result,"listdir_FAILURE ");
		strcat(result,ERR_VFS_LISTDIR_01);
		sprintf(str, "%s",result);
		return str;
		}					
	
		while(token!=NULL)
		{
			if(strcmp(rootnode->data,token)==0) // match
			{
			 prev = rootnode;
			 rootnode=rootnode->lchild;	 
			}

			else if(strcmp(rootnode->data,token)!=0) // no match
			{
				while((rootnode->rchild!=NULL)&&(strcmp(rootnode->data,token)!=0))
					rootnode=rootnode->rchild;
						 
				if(strcmp(rootnode->data,token)==0)
				{
				prev = rootnode;
				rootnode=rootnode->lchild;
				}
			}
		token=strtok(NULL,"/");
		}

		srcnode = prev;
			
		
		if(srcnode->lchild !=NULL)
		{
			srcnode=srcnode->lchild;
			fprintf(fop,"%s : %s\n",fd[srcnode->index].file_name,fd[srcnode->index].location_path);

			while(srcnode->rchild!=NULL)
			{
			srcnode=srcnode->rchild;
			fprintf(fop,"%s : %s\n",fd[srcnode->index].file_name,fd[srcnode->index].location_path);
			}
		}

		strcpy(result,"listdir_SUCCESS");
		sprintf(str, "%s",result);
		return str;

	}
	else
		{
		strcpy(result,"listdir_FAILURE ");
		strcat(result,ERR_VFS_LISTDIR_02);
		sprintf(str, "%s",result);
		return str;
		}
	fclose(fop);
}



void displayAll(node *root, FILE* fop){
	node * srcnode=root;
	if(root!=NULL){
	
	displayAll(root->lchild, fop);
	int a=srcnode->index;
		//printf("\n list dir loc path %s\n",fd[srcnode->index].location_path);
		//printf("\n list dir file name %s \n",fd[a].file_name);
	//printf(" %s\n",root->data);
	//printf("(parent=%s)",root->parent->data);
	fprintf(fop,"%s : %s\n",fd[a].file_name,fd[a].location_path);
	displayAll(root->rchild, fop);
	}	
}
